const
  csTranscodingInputFile = '-i "<INPUT FILE>"';
  csFFMpegVideoParams = ' -f %s -vcodec %s -b %d%s -aspect %s -copyts -pix_fmt yuv420p';
  csFFMpegAudioParams = ' -acodec %s -ab %d -ar 48000';

function GetAudioCodec(const aAudioCodec: string): string;
begin
  if (aAudioCodec = '') or SameText(aAudioCodec, 'AC3') or SameText(aAudioCodec, 'LPCM') then
    Result := 'ac3'
  else if SameText(aAudioCodec, 'AAC') then
    Result := 'libfaac'
  else if SameText(aAudioCodec, 'MP3') then
    Result := 'libmp3lame'
  else if SameText(aAudioCodec, 'MP2') then
    Result := 'mp2'
  else if SameText(aAudioCodec, 'WMA') then
    Result := 'wmav2'
  else
    Result := aAudioCodec
end;

function SameAudioCodec(const aAudioCodec: string; aCodecID: Integer): Boolean;
begin
  if (aAudioCodec = '') or SameText(aAudioCodec, 'AC3') then
    Result := aCodecID = CODEC_ID_AC3
  else if SameText(aAudioCodec, 'AAC') then
    Result := aCodecID = CODEC_ID_AAC
  else if SameText(aAudioCodec, 'MP3') then
    Result := aCodecID = CODEC_ID_MP3
  else if SameText(aAudioCodec, 'MP2') then
    Result := aCodecID = CODEC_ID_MP2
  else if SameText(aAudioCodec, 'WMA') then
    Result := aCodecID = CODEC_ID_WMAV2
  else
    Result := False
end;

function GetFileFormat(const aFileFormat: string): string;
begin
  if (aFileFormat = '') or SameText(aFileFormat, 'MPEG (DVD)') then
    Result := 'dvd'
  else if Pos('MPEGTS', aFileFormat) > 0 then
    Result := 'mpegts'
  else if Pos('ASF', aFileFormat) > 0 then
    Result := 'asf'
  else if SameText(aFileFormat, 'MP4') then
    Result := 'ipod'
  else if SameText(aFileFormat, 'MPEG1') then
    Result := 'mpeg'
  else
    Result := aFileFormat
end;

function GetVideoCodec(const aVideoCodec: string): string;
begin
  if (aVideoCodec = '') or SameText(aVideoCodec, 'MPEG2') then
    Result := 'mpeg2video'
  else if SameText(aVideoCodec, 'MPEG1') then
    Result := 'mpeg1video'
  else if SameText(aVideoCodec, 'WMV') then
    Result := 'wmv2'
  else if SameText(aVideoCodec, 'MPEG4') then
    Result := 'mpeg4'
  else if SameText(aVideoCodec, 'X264') then
    Result := 'libx264 -flags2 fastpskip -partitions none -flags none -sc_threshold 0 -trellis 0 -aq_mode 0 -me_method dia -rc_lookahead 0 -refs 1 -subq 0 '
  else
    Result := aVideoCodec
end;

function GetMultiThreadSupported(const aVideoCodec: string): Boolean;
begin
  if SameText(aVideoCodec, 'WMV') or SameText(aVideoCodec, 'MPEG1') then
    Result := False
  else
    Result := True
end;

function GetAudioBitrate(const aAudioCodec: string; aAudioBitrate: Integer): Integer;
begin
  if MatchText(aAudioCodec, ['MP2', 'MP3']) and (aAudioBitrate > 320000) then
    Result := 320000
  else
    Result := aAudioBitrate
end;

function GetAudioChannels(const aAudioCodec: string; aConfigAudioChannels, aStreamAudioChannels: Integer): Integer;
begin
  if aConfigAudioChannels > 0 then
    Result := aConfigAudioChannels
  else
    Result := aStreamAudioChannels;
  if (Result > 2) and MatchText(aAudioCodec, ['MP2', 'MP3']) then
    Result := 2
  else if (Result = 1) and MatchText(aAudioCodec, ['AAC', 'AC3']) then
    Result := 2
  else if Result > 6 then
    Result := 6
end;
  
var
  iAudioStreamNo, iChannels, iCodecID, iFrameWidth, iFrameHeight, 
  iWidth, iHeight, iPadLeft, iPadTop, iPadRight, iPadBottom: Integer;
  sFrameRate, sParams, sVideoMinMaxRate: string;
begin
  if cfgTranscodingVideoMinMaxRate then
    sVideoMinMaxRate := Format(' -minrate %d -maxrate %d -bufsize %d',
                [cfgTranscodingVideoBitrate, cfgTranscodingVideoBitrate, 
                 WmsTranscodingBufferSize(cfgTranscodingVideoBitrate)])
  else
    sVideoMinMaxRate := '';

  if mpInternetItem then
    TranscodingParams := WmsTranscodingProfileParams('Internet-television')
  else if mpSubItemsCount > 0 then 
    TranscodingParams := WmsTranscodingProfileParams('Movies (DVD)')
  else begin    
    sParams := WmsTranscodingInputParams;
    sParams := sParams + Format(csFFMPegVideoParams, [GetFileFormat(cfgTranscodingFileFormat),
           GetVideoCodec(cfgTranscodingVideoCodec), cfgTranscodingVideoBitrate,
           sVideoMinMaxRate, cfgTranscodingScreenFormat]);
    iAudioStreamNo := mpAudioStreamNo;
    if iAudioStreamNo <> -1 then begin
      iCodecID := WmsGetStreamCodecID('A', iAudioStreamNo);
      iChannels := WmsGetStreamChannels(iAudioStreamNo);
    end else begin
      iCodecID := CODEC_ID_NONE;
      iChannels := 0;
    end;
    if (iCodecID = CODEC_ID_NONE) and SameText(mpAudioCodec, 'AC3') then
      iCodecID := CODEC_ID_AC3;
    if cfgTranscodingAudioCopyAC3 and SameAudioCodec(cfgTranscodingAudioCodec, iCodecID) then
      sParams := sParams + ' -acodec copy'
    else begin
      sParams := sParams + Format(csFFMpegAudioParams, 
          [GetAudioCodec(cfgTranscodingAudioCodec), 
           GetAudioBitrate(cfgTranscodingAudioCodec, cfgTranscodingAudioBitrate)]);
      iChannels := GetAudioChannels(cfgTranscodingAudioCodec, cfgTranscodingAudioChannels, iChannels);
      if iChannels > 0 then
        sParams := sParams + ' -ac ' + IntToStr(iChannels)
    end;                                   
    sFrameRate := WmsGetVideoSettings(vstFrameRate);
    if sFrameRate = '' then    
      sFrameRate := cfgTranscodingFrameRate;
    if (mpFrameRate > 0) and (mpFrameRate < 25) then
      sFrameRate := '23.976';
    if (sFrameRate = '') then
      sFrameRate := '25';
    if sFrameRate <> '' then
      sParams := sParams + ' -r ' + sFrameRate;
    iWidth := mpWidth; iHeight := mpHeight;  
    if (iWidth > 0) and (iHeight > 0) then begin   
      if WmsTranscodingFrameParams(iWidth, iHeight, cfgTranscodingScreenFormat,
                         iPadLeft, iPadTop, iPadRight, iPadBottom) then begin
        iFrameWidth  := iWidth;
        iFrameHeight := iHeight;
        if (iPadLeft > 0) or (iPadRight > 0) or (iPadTop > 0) or (iPadBottom > 0) then begin
          sParams := sParams + Format(' -padleft %d -padright %d -padtop %d -padbottom %d -padcolor %s',
                      [iPadLeft, iPadRight, iPadTop, iPadBottom, WmsConvertColor(cfgTranscodingPadColor)]);
          if cfgTranscodingFrameExists then
            sParams := sParams + cfgTranscodingFrameParams;
          Inc(iFrameWidth,  iPadLeft + iPadRight);
          Inc(iFrameHeight, iPadTop + iPadBottom);
        end
      end else begin
        iFrameWidth  := iWidth;
        iFrameHeight := iHeight;
      end;
      sParams := sParams + Format(' -s %dx%d', [iWidth, iHeight]);
      sParams := sParams + WmsTranscodingSubTitleParams(
         iFrameWidth, iFrameHeight, iWidth, iHeight, iPadLeft, iPadTop);
      sParams := sParams + WmsTranscodingMapParams(iAudioStreamNo);
      if (cfgTranscodingThreadCount > 1) and GetMultiThreadSupported(cfgTranscodingVideoCodec) then
        sParams := sParams + ' -threads ' + IntToStr(cfgTranscodingThreadCount);
    end;
    TranscodingParams := sParams
  end  
end.